﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Xml;
using System.IO;
using System.Drawing;
using System.Windows.Forms;
using System.Xml.Linq;
using System.ComponentModel;

namespace GenIX.StyleSpace
{
    //<STYLES>---------------------------------------          Styles      </STYLES>     
    class Styles
    {

        public Styles(string path)
        {
            this.path = path;
            xmlDoc = new XmlDocument();
            Items = new List<Style>();
            Error = "";
            this.NoBag = StyleLoad(this.path);
        }
        // <LoadXmlInClass>загрузка стилей их XML </LoadXmlInClass>
        private bool StyleLoad(string path)
        {
            this.Error = "анализ загрузки Styles :\r\n";
            this.path = Path.GetDirectoryName(Application.ExecutablePath) + "\\Styles\\" + path;
            FileInfo fn = new FileInfo(this.path);
            if (fn.Exists != true)
            {
                this.Error += "ошибка чтения/записи документа, документ не найден";
                return false;
            }
            try
            {
                xdoc = XDocument.Load(this.path);
            }
            catch
            {
                this.Error += "ошибка чтения/записи документа, документ не найден";
                return false;
            }
            load loadForm = new load();
            bool selected = false;
            try
            {
                var query = from table in xdoc.Descendants("style")

                            select new
                            {
                                name = table.Attribute("name").Value,
                                active = table.Attribute("select").Value
                            };

                Style tempStyle;
                int countVal = query.Count();
                int i = 0;
                int percent = 0;

                loadForm.Show();

                foreach (var element in query)
                {
                    if (element.name == "")
                    {
                        this.Error += "\r\n" + "Найден безымянный стиль.Стиль не обработан!!!!" + "\r\n";
                        continue;
                    }
                    tempStyle = new Style(element.name);
                    //<GETTHAT> получаем конкретный стиль</GETTHAT>

                    var queryStyle = (from table in xdoc.Descendants("style")
                                      where table.Attribute("name").Value == element.name
                                      select table);
                    Error += "загружен стиль : " + element.name + "\r\n";
                    tempStyle.sbutton = SButton.ReadElement(queryStyle, element.name);
                    Error += " загружен элемент <Sbutton> : " + tempStyle.sbutton.Err + "";
                    tempStyle.slabel = SLabel.ReadElement(queryStyle, element.name);
                    Error += "загружен элемент <Slabel> : " + tempStyle.slabel.Err + "";
                    tempStyle.sform = SForm.ReadElement(queryStyle, element.name);
                    Error += "загружен элемент <Sform> : " + tempStyle.sform.Err + "";
                    tempStyle.sedit = SEdit.ReadElement(queryStyle, element.name);
                    Error += "загружен элемент <Sedit> : " + tempStyle.sedit.Err + "";
                    tempStyle.smenu = SMenu.ReadElement(queryStyle, element.name);
                    Error += "загружен элемент <Smenu> : " + tempStyle.smenu.Err + "";
                    if (element.active == "true")
                    {
                        tempStyle.CurrentStyle = true;
                        selected = true;
                    }
                    this.Items.Add(tempStyle);
                    i++;
                    percent = (int)((float)i / countVal * 100);
                    loadForm.progressBar1.Value = percent;
                    loadForm.toolStripStatusLabel1.Text = "загрузка стилей , количество :  " + i + "  " + percent + "%   " + element.name;
                }
            }
            catch { Error = "Ошибка в структуре документа XML "; return false; }
            if (!selected)
            {
                if (this.Items.Count() > 0)
                {
                    Items[0].CurrentStyle = true;
                }
                else
                {
                    this.Error = "Нет стилей";
                    return false;
                }
            }
            loadForm.Close();
            return true;
        }
        //<SET_ACTIVE> изменение активности стиля в XML </SET_ACTIVE>
        public void SetActiveStyle(string nameOld, string nameNew)
        {
            //<OLD> находим старый стиль и ставим его в фолс </OLD>
            var qOld = from table
            in xdoc.Descendants("style").
            Where(key => key.Attribute("name").Value == nameOld)
                       select table.Attribute("select");
            //<NEW>находим новый стиль и ставим его в актив </NEW>   
            foreach (var val in qOld) val.Value = "false";
            var qNew = from table
                 in xdoc.Descendants("style").
                 Where(key => key.Attribute("name").Value == nameNew)
                       select table.Attribute("select");
            foreach (var val in qNew) val.Value = "true";
            xdoc.Save(this.path);
        }
        //<GET_STYLE> получение стиля по имени</GET_STYLE>
        public Style getStyle(string name)
        {
            for (int i = 0; i < Items.Count; i++)
            {
                if (Items[i].name == name)
                    return Items[i];
            }
            return null;
        }
        //<CHANGE_STYLE> изменения стиля в XML</CHANGE_STYLE>
        public void ChangeStyle(Style temp)
        {
            string nameStyle = temp.name;
            var style = (from table in xdoc.Descendants("style")
                         where table.Attribute("name").Value == nameStyle
                         select table);

            foreach (var a in style)
            {
                XElement element = (XElement)a;
                XNode node = element.FirstNode;
                while (node != null)
                {
                    XElement st = (XElement)node;
                    node = node.NextNode;
                    st.Remove();
                }
                Add(temp, element);
            }

            xdoc.Save(path);

        }
        //<REMOVE_S> удаление стиля из объекта и XML</REMOVE_S>
        public void Remove(string nameStyle)
        {
            //<REM_OBJ> удаляем объект </REM_OBJ>
            this.Items.Remove(this.getStyle(nameStyle));
            var style = (from table in xdoc.Descendants("style")
                         where table.Attribute("name").Value == nameStyle
                         // <THAT_STYLE>получаем конкретный стиль</THAT_STYLE>
                         select table);
            //<FROM_XML> и удаляем стиль из xml</FROM_XML>
            style.Remove();
            xdoc.Save(this.path);
        }
        //<STYLE_TEMP> шаблон создания стиля</STYLE_TEMP>
        public void Add(Style tempStyle, XElement root)
        {
            XElement color;
            XElement font;
            XElement fontSize;
            XElement foreColor;
            XElement fontStyle;

            if (tempStyle.sbutton.check == true)
            {

                color = new XElement("color", tempStyle.sbutton.ColorT);
                font = new XElement("font", tempStyle.sbutton.FontFamalyT);
                fontSize = new XElement("fontSize", tempStyle.sbutton.FontSizeT);
                foreColor = new XElement("foreColor", tempStyle.sbutton.ForeColorT);
                fontStyle = new XElement("fontStyle", tempStyle.sbutton.FontStyleT);

                XElement sbutton = new XElement("Sbutton",
                       color,
                       font,
                       fontSize,
                       foreColor,
                       fontStyle
                       );
                root.Add(sbutton);
            }

            if (tempStyle.sedit.check == true)
            {

                color = new XElement("color", tempStyle.sedit.ColorT);
                font = new XElement("font", tempStyle.sedit.FontFamalyT);
                fontSize = new XElement("fontSize", tempStyle.sedit.FontSizeT);
                foreColor = new XElement("foreColor", tempStyle.sedit.ForeColorT);
                fontStyle = new XElement("fontStyle", tempStyle.sedit.FontStyleT);

                XElement sedit = new XElement("Sedit",
                    color,
                    font,
                    fontSize,
                    foreColor,
                    fontStyle
                   );
                root.Add(sedit);
            }

            if (tempStyle.sform.check == true)
            {

                color = new XElement("color", tempStyle.sform.ColorT);
                font = new XElement("font", tempStyle.sform.FontFamalyT);
                fontSize = new XElement("fontSize", tempStyle.sform.FontSizeT);
                foreColor = new XElement("foreColor", tempStyle.sform.ForeColorT);
                fontStyle = new XElement("fontStyle", tempStyle.sform.FontStyleT);

                XElement sform = new XElement("Sform",
                    color,
                    font,
                    fontSize,
                    foreColor,
                    fontStyle
                   );
                root.Add(sform);
            }

            if (tempStyle.slabel.check == true)
            {

                color = new XElement("color", tempStyle.slabel.ColorT);
                font = new XElement("font", tempStyle.slabel.FontFamalyT);
                fontSize = new XElement("fontSize", tempStyle.slabel.FontSizeT);
                foreColor = new XElement("foreColor", tempStyle.slabel.ForeColorT);
                fontStyle = new XElement("fontStyle", tempStyle.slabel.FontStyleT);
                XElement slabel = new XElement("Slabel",
                   color,
                   font,
                   fontSize,
                   foreColor,
                   fontStyle
                  );
                root.Add(slabel);
            }

            if (tempStyle.smenu.check == true)
            {

                color = new XElement("color", tempStyle.smenu.ColorT);
                font = new XElement("font", tempStyle.smenu.FontFamalyT);
                fontSize = new XElement("fontSize", tempStyle.smenu.FontSizeT);
                foreColor = new XElement("foreColor", tempStyle.smenu.ForeColorT);
                fontStyle = new XElement("fontStyle", tempStyle.smenu.FontStyleT);
                XElement smenu = new XElement("Smenu",
                    color,
                    font,
                    fontSize,
                    foreColor,
                    fontStyle
                   );
                root.Add(smenu);
            }
        }
        //<ADD_NEW> добавление нового стиля в объект и  XML </ADD_NEW>
        public void AddStyle(Style st)
        {
            Style tempStyle = st;
            XElement root = new XElement("style",
                new XAttribute("name", tempStyle.name),
                new XAttribute("select", "false")
                );
            Add(tempStyle, root);
            xdoc.Element("styles").Add(root);
            try
            {
                xdoc.Save(path);
                this.Items.Add(tempStyle);
            }
            catch { MessageBox.Show("error Write XML DOC"); }

        }
        public Style this[int i]
        {
            get { return Items[i]; }
        }
        public Style this[string name]
        {
            get { return getStyle(name); }
        }
        private XmlDocument xmlDoc;
        public List<Style> Items;
        public string Error;
        public bool NoBag = false;
        XDocument xdoc;
        string path;
        public int Count { get { return Items.Count(); } }
    }
    class Style : ICloneable
    {
        public string name;
        public bool CurrentStyle = false;
        public Style(string name)
        {
            //<DEFAULT_EL> при создании нового стиля ставлю элементы в default</DEFAULT_EL>
            sbutton = new SButton();
            slabel = new SLabel();
            sedit = new SEdit();
            smenu = new SMenu();
            sform = new SForm();
            this.name = name;
        }
        public SButton sbutton;
        public SLabel slabel;
        public SEdit sedit;
        public SMenu smenu;
        public SForm sform;

        //<CLONE> Клон класса ICloneable</CLONE>
        public Object Clone()
        {
            Style style = new Style(this.name);
            style.sbutton.check = this.sbutton.check;
            style.sbutton.colorS = this.sbutton.colorS;
            style.sbutton.ColorT = this.sbutton.ColorT;
            style.sbutton.Err = this.sbutton.Err;
            style.sbutton.fontFamalyS = this.sbutton.fontFamalyS;
            style.sbutton.FontFamalyT = this.sbutton.FontFamalyT;
            style.sbutton.FontS = this.sbutton.FontS;
            style.sbutton.fontSizeS = this.sbutton.fontSizeS;
            style.sbutton.FontSizeT = this.sbutton.FontSizeT;
            style.sbutton.foreColorS = this.sbutton.foreColorS;
            style.sbutton.ForeColorT = this.sbutton.ForeColorT;
            style.sbutton.FontStyleT = this.sbutton.FontStyleT;

            style.slabel.check = this.slabel.check;
            style.slabel.colorS = this.slabel.colorS;
            style.slabel.ColorT = this.slabel.ColorT;
            style.slabel.Err = this.slabel.Err;
            style.slabel.fontFamalyS = this.slabel.fontFamalyS;
            style.slabel.FontFamalyT = this.slabel.FontFamalyT;
            style.slabel.FontS = this.slabel.FontS;
            style.slabel.fontSizeS = this.slabel.fontSizeS;
            style.slabel.foreColorS = this.slabel.foreColorS;
            style.slabel.ForeColorT = this.slabel.ForeColorT;
            style.slabel.FontStyleT = this.slabel.FontStyleT;
            style.slabel.FontSizeT = this.slabel.FontSizeT;

            style.sedit.check = this.sedit.check;
            style.sedit.colorS = this.sedit.colorS;
            style.sedit.ColorT = this.sedit.ColorT;
            style.sedit.Err = this.sedit.Err;
            style.sedit.fontFamalyS = this.sedit.fontFamalyS;
            style.sedit.FontFamalyT = this.sedit.FontFamalyT;
            style.sedit.FontS = this.sedit.FontS;
            style.sedit.fontSizeS = this.sedit.fontSizeS;
            style.sedit.foreColorS = this.sedit.foreColorS;
            style.sedit.ForeColorT = this.sedit.ForeColorT;
            style.sedit.FontStyleT = this.sedit.FontStyleT;
            style.sedit.FontSizeT = this.sedit.FontSizeT;

            style.smenu.check = this.smenu.check;
            style.smenu.colorS = this.smenu.colorS;
            style.smenu.ColorT = this.smenu.ColorT;
            style.smenu.Err = this.smenu.Err;
            style.smenu.fontFamalyS = this.smenu.fontFamalyS;
            style.smenu.FontFamalyT = this.smenu.FontFamalyT;
            style.smenu.FontS = this.smenu.FontS;
            style.smenu.fontSizeS = this.smenu.fontSizeS;
            style.smenu.foreColorS = this.smenu.foreColorS;
            style.smenu.ForeColorT = this.smenu.ForeColorT;
            style.smenu.FontStyleT = this.smenu.FontStyleT;
            style.smenu.FontSizeT = this.smenu.FontSizeT;

            style.sform.check = this.sform.check;
            style.sform.colorS = this.sform.colorS;
            style.sform.ColorT = this.sform.ColorT;
            style.sform.Err = this.sform.Err;
            style.sform.fontFamalyS = this.sform.fontFamalyS;
            style.sform.FontFamalyT = this.sform.FontFamalyT;
            style.sform.FontS = this.sform.FontS;
            style.sform.fontSizeS = this.sform.fontSizeS;
            style.sform.foreColorS = this.sform.foreColorS;
            style.sform.ForeColorT = this.sform.ForeColorT;
            style.sform.FontStyleT = this.sform.FontStyleT;
            style.sform.FontSizeT = this.sform.FontSizeT;
            return style;
        }
    }

}

